home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / hypercar / xfcn / spttool.cpt / Support Tools eXternals 1.2.5 / card_32930.txt < prev    next >
Text File  |  1990-11-13  |  10KB  |  310 lines

  1. -- card: 32930 from stack: in.5
  2. -- bmap block id: 42726
  3. -- flags: 0000
  4. -- background id: 3858
  5. -- name: EjectDisk
  6. ----- HyperTalk script -----
  7. on hideObjects
  8.   hide cd btn "Try It!"
  9. end hideObjects
  10.  
  11. on showObjects
  12.   show cd btn "Try It!"
  13. end showObjects
  14.  
  15.  
  16. -- part 4 (button)
  17. -- low flags: 00
  18. -- high flags: A002
  19. -- rect: left=82 top=185 right=219 bottom=175
  20. -- title width / last selected line: 0
  21. -- icon id / first selected line: 0 / 0
  22. -- text alignment: 1
  23. -- font id: 0
  24. -- text size: 12
  25. -- style flags: 8192
  26. -- line height: 16
  27. -- part name: Try it!
  28. ----- HyperTalk script -----
  29. on mouseUp
  30.   -- eject the specified disk
  31.   global errGlobal
  32.   put volumePath() into newVolume
  33.   if newVolume = empty then exit mouseUp
  34.   EjectDisk newVolume, "noDialog:errGlobal"
  35.   if errGlobal Γëá empty then
  36.     answer "Error: ΓÇ£" & errGlobal & "ΓÇ¥"
  37.     put empty into errGlobal
  38.   end if
  39. end mouseUp
  40.  
  41.  
  42.  
  43.  
  44. -- part contents for background part 38
  45. ----- text -----
  46. 13/50
  47.  
  48. -- part contents for background part 20
  49. ----- text -----
  50.      This XCMD will unmount and eject the specified disk.  Trying to eject a non-removable disk will return an error message unless the second parameter to the XCMD is the literal string "EjectAll", in which case the XCMD will attempt to eject any disk.  If you specify "EjectAll" and attempt to eject the start-up volume (the disk which has the active system folder on it) the volume will be unmounted/ejected and an error message will be returned.  
  51.      It is probably wise to make sure that no files on the disk to be ejected are open before using this XCMD (see the ΓÇ£OpenFilesΓÇ¥ XFCN in this stack).  Applications may behave unpredictably, and/or files may be corrupted if you remove a volume without first closing all files on it.  Although the XCMD returns an error message if a file (other than the Desktop) is open on a drive which has been ejected, by then the damage may have already been done.
  52.  
  53.      Calling Syntax: EjectDisk volumeName, <"EjectAll">, <"noDialog:"errorGlobal>
  54. VOLUMENAME :  the name of the disk to be ejected.
  55.  
  56. -- part contents for background part 42
  57. ----- text -----
  58. { ejectDisk(VolName ┬½,ΓÇ£noDialog:ΓÇ¥errorGlobal┬╗)}
  59. { XCMD to unmount and eject a disk}
  60. {}
  61. {   brought to you by:    Anup Murarka           Eric Carlson          }
  62. {                       ALINK:  SKEPTIC           ALINK:  cyNic   }
  63. {                                   CIS:  76004,3356        }
  64. {}
  65. {               We are part of the Support Tools Development Group,    }
  66. {               Apple Computer, Inc.      }
  67. {}
  68. {               please DO NOT contact Mac DTS for support of this code!   }
  69. {}
  70. {               please DO contact the authors for support of this code!  }
  71. {}
  72. {               Send comments, bug reports, requests to any of the above    }
  73. {               E-mail addresses or to:}
  74. {}
  75. {                           (one of us)                    }
  76. {                           Apple Computer, Inc.          }
  77. {                           900 E. Hamilton, Ave.       }
  78. {                           Campbell, CA   95008       }
  79. {                           M/S 72-L                     }
  80. {}
  81. {   Copyright:    ┬⌐ 1989, 1990 by Apple Computer, Inc., all rights reserved.     }
  82. {}
  83. { written by Eric Carlson                                      }
  84. { AppleLink:  cyNic                                                }
  85. { modification history                                           }
  86. {          Date              Initials                                      Comments                             }
  87. {          ----              ------      ------------------------------------------------------}
  88. {       3/1/90            ec              first written                                                        }
  89. {       6/6/90            ec              fixed error in reading ΓÇ£EJECTALLΓÇ¥ parameter, added      }
  90. {       5/31/90          ec              additional comments to code                                         }
  91. {}
  92.  
  93. unit EjectDisk;
  94.  
  95. interface
  96.  
  97.  uses
  98.   HyperXCmd;
  99.  
  100.  procedure MAIN (paramPtr: XCmdPtr);
  101.  
  102. implementation
  103.  
  104.  procedure reportToUser (paramPtr: XCmdPtr;
  105.        msgStr: str255);
  106. {}
  107. { report something back to the user.  }
  108. { the last parameter (optional) to an external may contain }
  109.  { "noDialog" or "noDialog:GlobalName".  GlobalName is the name }
  110.  { of a HyperTalk global variable into which error messages will be }
  111.  { placed.  we've decided to use this approach to avoid confusing }
  112. { an error message with a valid result being returned from an XFCN. }
  113. {}
  114.   var
  115.    tempStr: str255;
  116.  begin
  117. {check the last param to see if the user requested that}
  118. { we suppress the error dialog }
  119.   ZeroToPas(paramPtr, paramPtr^.params[paramPtr^.paramCount]^, tempStr);
  120.   UprString(tempStr, true);
  121.   if pos('NODIALOG', tempStr) = 0 then
  122. { no special error handling specified, throw up a dialog and return the error message }
  123.    begin
  124.     SendCardMessage(paramPtr, concat('answer "', msgStr, '"'));
  125.     paramPtr^.returnValue := PasToZero(paramPtr, msgStr);
  126.    end
  127.   else if (pos(':', tempStr) > 0) then
  128. { requested global AND noDialog so we fill in the global and return empty }
  129.    begin
  130.     tempStr := copy(tempStr, pos(':', tempStr) + 1, length(tempStr));
  131. { get the name of the HC global  to fill }
  132.     SetGlobal(paramPtr, tempStr, PasToZero(paramPtr, msgStr));
  133. { and fill it }
  134.     paramPtr^.returnValue := PasToZero(paramPtr, '');{ return empty }
  135.    end
  136.   else
  137. { requested noDialog only so we return the error condition as the result }
  138.    paramPtr^.returnValue := PasToZero(paramPtr, msgStr);
  139.  end;{ procedure }
  140.  
  141.  function AskedForHelp (paramPtr: XCmdPtr;
  142.        syntaxMsg: Str255;
  143.        copyrightMsg: Str255): boolean;
  144. {check to see if the user sent a '?' or a '!' as }
  145. { the only parameter. if so we will respond with }
  146. { the calling syntax or the copyright/version info }
  147. { for this external }
  148. {}
  149.   var
  150.    firstStr: str255;
  151.  begin
  152.   askedForHelp := false;
  153.   if paramPtr^.paramCount = 1 then
  154.    begin
  155.     ZeroToPas(paramPtr, paramPtr^.params[1]^, firstStr);
  156. { what is the first param? }
  157.     if firstStr = '?' then
  158.      begin
  159.       reportToUser(paramPtr, syntaxMsg);
  160.       askedForHelp := true
  161.      end{ asked for help }
  162.     else if firstStr = '!' then
  163.      begin
  164.       reportToUser(paramPtr, copyRightMsg);
  165.       askedForHelp := true
  166.      end;{ asked for copyright info }
  167.    end;{ one parameter passed }
  168.  end;{ function }
  169.  
  170.  function NumberToString (paramPtr: XCmdPtr;
  171.        num: LONGINT): Str255;
  172. { use the toolbox call rather than HC's }
  173.   var
  174.    tempStr: str255;
  175.  begin
  176.   NumToString(num, tempStr);
  177.   NumberToString := tempStr;
  178.  end;
  179.  
  180.  procedure ReportVolError (paramPtr: XCmdPtr;
  181.        errorNum: integer);
  182.   var
  183.    errMsg, tempName: str255;
  184.  begin
  185.   case errorNum of{ what caused the problem? }
  186.    bdNamErr: 
  187.     errMsg := 'Bad volume name.';
  188.    extFSErr: 
  189.     errMsg := 'External file system.';
  190.    ioErr: 
  191.     errMsg := 'I/O Error.';
  192.    nsDrvErr: 
  193.     errMsg := 'No such drive.';
  194.    nsvErr: 
  195.     errMsg := 'No such volume.';
  196.    paramErr: 
  197.     errMsg := 'No default volume.';
  198.    otherwise
  199.     errMsg := concat('unexpected error #', NumberToString(paramPtr, errorNum));
  200.   end;{ case }
  201.  
  202.   errMsg := concat('Sorry, ', errMsg);
  203.   reportToUser(paramPtr, errMsg);
  204. { return the error message }
  205.  end;{ function }
  206.  
  207.  function validVolumeName (volumeName: str255): str255;
  208. { a volume name must have one (and only one) colon in it, as }
  209. { the last character }
  210.  begin
  211.   if pos(':', volumeName) = 0 then
  212.    validVolumeName := concat(volumeName, ':')
  213.   else
  214.    validVolumeName := copy(volumeName, 1, pos(':', volumeName));
  215.  end;
  216.  
  217.  function DriveRemovable (aDQEPtr: DrvQElPtr): boolean;
  218.   var
  219.    flagsPtr: ^longint;
  220.  begin
  221. {subtract 4 from the DrvQE1Ptr to grab the long there }
  222.   flagsPtr := pointer(ord4(aDQEPtr) - 4);
  223.   DriveRemovable := (BAND(BSR(flagsPtr^, 16), $FF) <> 8);
  224.  end;
  225.  
  226.  function DriveNumToQueElement (driveNum: integer): DrvQElPtr;
  227. { given a drive number, return a drive que pointer for that drive}
  228. { 12:32 PM 3/1/90 ec }
  229.   var
  230.    aQueElement: DrvQElPtr;
  231.    headPtr: QHdrPtr;
  232.  begin
  233.   headPtr := GetDrvQHdr;{ grab the drive que header }
  234.   if headPtr <> nil then
  235.    begin
  236.     aQueElement := DrvQElPtr(headPtr^.qHead);
  237.     while (aQueElement^.dQDrive <> driveNum) and (aQueElement <> nil) do
  238.      aQueElement := DrvQElPtr(aQueElement^.qLink);
  239.     DriveNumToQueElement := aQueElement;
  240.    end
  241.   else
  242.    DriveNumToQueElement := nil;
  243.  end;
  244.  
  245.  procedure ejectDisk (paramPtr: XCmdPtr);
  246.   var
  247.    volToEject, tempVar: str255;
  248.    PB: HParamBlockRec;
  249.    errorCode: OSErr;
  250.  begin
  251.   if AskedForHelp(paramPtr, 'EjectDisk diskName, ┬½ΓÇ£EjectAllΓÇ¥┬╗, ┬½ΓÇ£noDialog:ΓÇ¥errorGlobal┬╗', '┬⌐ 1990 Apple Computer, Inc. v.1.1,  bu Eric Carlson.') then
  252.    exit(EjectDisk);
  253.  
  254.   if paramPtr^.paramCount = 0 then
  255.    begin
  256.     ReportToUser(paramPtr, 'Disk name expected.');
  257.     exit(EjectDisk);
  258.    end
  259.   else
  260.    ZeroToPas(paramPtr, paramPtr^.Params[1]^, volToEject);
  261.  
  262.   volToEject := validVolumeName(volToEject);{ make sure the volume name is correct }
  263.  
  264.  
  265. {  Since volToEject is a full pathname, no other field is needed}
  266.   zeroBytes(paramPtr, @PB, sizeOf(PB));{ initialize parameter block. }
  267.   PB.ioNamePtr := @volToEject;{ the name }
  268.   PB.ioVolIndex := -1;{ use name ONLY }
  269.   errorCode := PBHGetVInfo(@PB, false);
  270.   if errorCode <> noErr then{ any errors? }
  271.    begin
  272.     reportVolError(paramPtr, errorCode);
  273.     exit(EjectDisk);
  274.    end;
  275.  
  276.   tempVar := '';{ no value for the var yet }
  277.   if not (DriveRemovable(DriveNumToQueElement(PB.ioVDrvInfo))) then
  278. { this disk is not removable, check to see if user specified that we should do an "eject" anyway }
  279.    if paramPtr^.paramCount > 1 then
  280.     begin
  281.      ZeroToPas(paramPtr, paramPtr^.Params[2]^, tempVar);
  282.      UprString(tempVar, true);{ upper case for comparison }
  283.     end;
  284.   if tempVar <> 'EJECTALL' then{ don't call eject trap unless specifically instructed to }
  285.    begin
  286.     ReportToUser(paramPtr, 'Drive is not removable');
  287.     exit(EjectDisk)
  288.    end;
  289.  
  290.   errorCode := PBEject(@PB);{ call for the eject }
  291.   if errorCode <> noErr then{ error? }
  292.    begin
  293.     reportVolError(paramPtr, errorCode);
  294.     exit(ejectDisk);
  295.    end;
  296.  
  297.   errorCode := PBUnmountVol(@PB);{ now call for the unmount }
  298.   if errorCode <> noErr then{ error? }
  299.    begin
  300.     reportVolError(paramPtr, errorCode);
  301.     exit(ejectDisk);
  302.    end;
  303.  end;{ procedure EjectDisk}
  304.  
  305.  procedure MAIN (paramPtr: XCmdPtr);
  306.  begin
  307.   ejectDisk(paramPtr);
  308.  end;
  309.  
  310. end.{ unit EjectDisk}